package com.formerlyknownasprince.wheresmystuff.models;

import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

import com.formerlyknownasprince.wheresmystuff.R;


/**
 * @author      Tim Swihart 		<email obscured since this file is public>
 * @version     0.25               
 * @since       2013-03-04
 */
@JsonIgnoreProperties(ignoreUnknown=true)
public abstract class ServerObject {
	
	protected static ObjectMapper om;
	protected static DefaultHttpClient http;
	protected static final String rootURL = "http://128.61.104.203";
	//protected String baseURL;
	protected int id;
	
	public abstract JsonNode toJson();
	
	@JsonIgnore
	public static void setObjectMapper(ObjectMapper omap) {
		om = omap;
	}
	
	@JsonIgnore
	public static void setHttpClient(DefaultHttpClient hc) {
		http = hc;
	}
	
	/**
	 * Synchronizes this object with the server, saving any changes/creating/deleting based on the passed in request
	 * @throws SyncException
	 * @throws IOException 
	 * @throws ClientProtocolException 
	 */
	private void sync(HttpRequestBase req) throws SyncException, ClientProtocolException, IOException {
		HttpResponse response = http.execute(req);
		
		InputStream is = response.getEntity().getContent();
		
		ObjectMapper mapper = new ObjectMapper();
		JSONMessage msg = new JSONMessage(mapper.readValue(is, JsonNode.class));
		
		if (msg.getErr().length() > 0) {
			throw new SyncException(msg.getErr());
		}
	}
	
	/**
	 * Creates a destroy request and sends it to the server
	 * @throws ClientProtocolException
	 * @throws SyncException
	 * @throws IOException
	 */
	protected void destroy() throws ClientProtocolException, SyncException, IOException {
		HttpDelete destroyReq = new HttpDelete(rootURL+getBaseURL() + this.id);
		
		this.sync(destroyReq);
	}
	
	/**
	 * Creates and sends an update request to the server
	 * @throws SyncException
	 * @throws JsonGenerationException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	protected void update() throws SyncException, JsonGenerationException, JsonMappingException, IOException {
		HttpPut updateReq = new HttpPut(rootURL+getBaseURL() + this.id);
		String json = om.writeValueAsString(this.toJson());
		updateReq.setEntity(new StringEntity(json));
		
		this.sync(updateReq);
	}
	
	/**
	 * Creates a create object request and sends it to the server
	 * @throws SyncException
	 * @throws JsonGenerationException
	 * @throws JsonMappingException
	 * @throws IOException
	 */
	protected void create() throws SyncException, JsonGenerationException, JsonMappingException, IOException {
		HttpPost createReq = new HttpPost(rootURL+getBaseURL()+"/new");
		String json = om.writeValueAsString(this.toJson());
		createReq.setEntity(new StringEntity(json));
		
		this.sync(createReq);
	}

	public class SyncException extends Exception {

		/**
		 * auto-generated to make Eclipse happy
		 */
		private static final long serialVersionUID = -4794723417504642131L;

		public SyncException(String string) {
			// TODO Auto-generated constructor stub
		}		
	}

	public String getBaseURL() {
		return "";
	}
}
